package com.rongzhe.house.house.service;

import com.alibaba.fastjson.JSONObject;
import com.rongzhe.house.common.resp.ApiResult;
import com.rongzhe.house.common.utils.PageUtils;
import com.rongzhe.house.house.criteria.HouseCriteria;
import com.rongzhe.house.house.criteria.HouseMapCriteria;
import com.rongzhe.house.house.dao.*;
import com.rongzhe.house.house.entity.*;
import com.rongzhe.house.house.enums.UserCollectionType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by hggxg on 2017/11/18.
 */
@Slf4j
@Service
public class HouseServiceImpl implements HouseService {

    public static final String WEB_HOUSE_INDEX = "house";

    @Autowired
    private HouseBaseMapper houseBaseMapper;

    @Autowired
    private HouseRoomLiveInfoMapper houseRoomLiveInfoMapper;


    @Autowired
    private HouseRentPaymentConfigMapper houseRentPaymentConfigMapper;

    @Autowired
    private HouseImageMapper houseImageMapper;

    @Autowired
    private HouseTrafficMapper houseTrafficMapper;

    @Autowired
    private Client client;

    @Autowired
    private UserCollectionMapper userCollectionMapper;

    @Autowired
    private LifeServiceMapper lifeServiceMapper;

    @Autowired
    private HouseDelegationApplyMapper houseDelegationApplyMapper;

    @Override
    public boolean delegationApply(HouseDelegationApply delegationApply,Integer userId) {

        //魔数
        delegationApply.setFlag("1");

        delegationApply.setInsertTime(new Date());

        //delegationApply.setInsertUid(userId);

        int result = houseDelegationApplyMapper.insertSelective(delegationApply);

        return result == 1;
    }


    @Override
    public List<LifeService> getLifeService(Integer type) {
        return lifeServiceMapper.selectByType(type);
    }

    @Override
    public boolean hasCollection(Integer houseId, Integer userId) {
        UserCollection userCollectionSelect = userCollectionMapper
                .selectByUidAndTypeAndBizIdForUpdate(userId, UserCollectionType.HOUSE.getType(), houseId);

        if (userCollectionSelect == null) {
            //没有收藏
            return false;
        } else {
            //已经收藏了，取消收藏
            return true;
        }
    }
    @Override
    public boolean collection(Integer houseId, Integer userId) {


        UserCollection userCollectionSelect = userCollectionMapper
                .selectByUidAndTypeAndBizIdForUpdate(userId, UserCollectionType.HOUSE.getType(), houseId);


        if (userCollectionSelect == null) {
            //没有收藏
            UserCollection userCollection = new UserCollection();
            userCollection.setUid(userId);
            userCollection.setBizId(houseId);
            userCollection.setInsertUid(userId);
            userCollection.setType((byte) UserCollectionType.HOUSE.getType());
            userCollectionMapper.insertSelective(userCollection);
            return true;
        } else {
            //已经收藏了，取消收藏
            userCollectionMapper.deleteByPrimaryKey(userCollectionSelect.getId());
            return false;
        }
    }

    @Override
    public List<HouseOverview> getExcellentHouse(String cityId) {

        return houseBaseMapper.selectExcellentHouse(cityId);

    }

    @Override
    public ApiResult getExcellentHouse(String cityId, boolean isEntreRent, boolean isOwnerRent) {
        HouseCriteria houseCriteria=new HouseCriteria();
        houseCriteria.setEntireRent(isEntreRent);
        houseCriteria.setOwnerRent(isOwnerRent);
        houseCriteria.setCityId(cityId);

        /*long count=houseBaseMapper.countExcellentHouse(houseCriteria);
        if(count==0){
            return ApiResult.buildOk();
        }*/
        //PageUtils.initPageParam(houseCriteria);
        return ApiResult.buildOk(houseBaseMapper.getExcellentHouse(houseCriteria));
    }

    @Override
    public List<HouseOverview> selectHouseByIds(List<Long> ids) {
        /*List<HouseOverview> houseOverviews = selectHouseByIds(ids, null, null);
        for(HouseOverview houseOverview:houseOverviews){
            houseBase.setTagList(houseTagMapper.selectByHouseId(houseBase.getId()));
            houseBase.setHouseTrafficList(houseTrafficMapper.selectListByHouseId(houseBase.getId()));
            houseBase.setCityId("5001");
            list.add(houseBase);
        }*/

        return null;
    }

    @Override
    public List<HouseOverview> selectHouseByIds(List<Long> ids,String orderStr,String order) {
        return houseBaseMapper.selectHouseByIds(ids,orderStr,order);
    }

    @Override
    public List<HouseOverview> queryHouseByCriteria(HouseCriteria houseCriteria) {


        int total = houseBaseMapper.countHouseByCriteria(houseCriteria);


        if (total == 0) {
            return null;
        }

        int offset = houseCriteria.getPageSize() * (houseCriteria.getCurrentPage() - 1);

        int limit = houseCriteria.getPageSize();

        houseCriteria.setOffset(offset);
        houseCriteria.setLimit(limit);

        List<HouseOverview> houseOverviews = houseBaseMapper.selectHouseByCriteria(houseCriteria);


        return houseOverviews;
    }

    @Override
    public HouseDetail detail(Integer houseId) {

        HouseDetail houseDetail = houseBaseMapper.selectDetailById(houseId);

        if (houseDetail != null) {
            houseDetail.setHouseRoomLiveInfoList(houseRoomLiveInfoMapper.selectRoomInfoListByHouseId(houseId));

            houseDetail.setHouseImageList(houseImageMapper.selectListByHouseId(houseId));

            houseDetail.setHouseTrafficList(houseTrafficMapper.selectListByHouseId(houseId));
            houseDetail.setHouseLiveInfoOverviews(houseBaseMapper.selectHouseLiveInfo(houseId));

            houseDetail.setHouseTags(houseBaseMapper.queryHouseTagById(houseId));

        }

        return houseDetail;
    }

    @Override
    public List<HouseRentPaymentConfig> getHouseRentPayConfigListByHouseId(Integer houseId) {


        return houseRentPaymentConfigMapper.selectHouseRentPayConfigListByHouseId(houseId);

    }

    /**
     * 地图搜索
     * @param houseCriteria
     * @return
     */
    @Override
    public JSONObject map(HouseMapCriteria houseCriteria){

        houseCriteria.setCurrentPage(houseCriteria.getP());
        PageUtils.initPageParam(houseCriteria);//分页


        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("cityId", houseCriteria.getCityId() == null ? "5001" : houseCriteria.getCityId()));


        if(!StringUtils.isEmpty(houseCriteria.getResblock_id())){
            boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("code",houseCriteria.getResblock_id()));
        }

        if(!StringUtils.isEmpty(houseCriteria.getQuery())){
            boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("name",houseCriteria.getQuery()));
        }

        if (!StringUtils.isEmpty(houseCriteria.getCountyId())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("countyId", houseCriteria.getCountyId()));
        }

        if (!StringUtils.isEmpty(houseCriteria.getTownId())) {
            boolQueryBuilder.must(QueryBuilders.termQuery("townId", houseCriteria.getTownId()));
        }

        if (!StringUtils.isEmpty(houseCriteria.getKeyword())) {
            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(houseCriteria.getKeyword(), "name", "countyName", "route", "station"));
        }

        chooseHouseType(houseCriteria,boolQueryBuilder);

        if (houseCriteria.getRoute() != null) {
            boolQueryBuilder
                    .must(QueryBuilders.termsQuery("railList", houseCriteria.getRoute()));
        }

       if (houseCriteria.isFindRound()) {
            GeoPoint geoPoint = new GeoPoint();
            geoPoint.reset(houseCriteria.getClat(),houseCriteria.getClng());
            boolQueryBuilder.must(QueryBuilders.geoDistanceQuery("location")
                    .point((houseCriteria.getMin_lat()+houseCriteria.getMax_lat())/2,(houseCriteria.getMin_lng()+houseCriteria.getMax_lng())/2)
                    .distance(85, DistanceUnit.KILOMETERS));
        }

        //AggregationBuilders.terms("").field("location");

        SearchRequestBuilder srb1 = client
                .prepareSearch(WEB_HOUSE_INDEX)
                .setQuery(boolQueryBuilder)
                .setFrom(houseCriteria.getOffset())
                .setSize(houseCriteria.getPageSize())
                ;
        if(StringUtils.isBlank(houseCriteria.getOrderStr())||StringUtils.isBlank(houseCriteria.getOrder())){
           srb1.addSort("insertTime", SortOrder.DESC);
        }else{
            /*if("desc".equals(houseCriteria.getOrder())){
                srb1.addSort(houseCriteria.getOrderStr(), SortOrder.DESC);
            }else{
                srb1.addSort(houseCriteria.getOrderStr(), SortOrder.ASC);
            }*/
        }

        MultiSearchResponse sr = client.prepareMultiSearch()
                .add(srb1)
                .get();
        List<Long> ids = new ArrayList<>();
        List<Map<String,Object>> datas=new ArrayList<Map<String,Object>>();
        JSONObject jsonObject=new JSONObject();
        for (MultiSearchResponse.Item item : sr.getResponses()) {

            SearchResponse response = item.getResponse();

            if(response == null){
                continue;
            }
            SearchHit[] searchHits = response.getHits().getHits();
            if (searchHits != null && searchHits.length != 0) {
                for (int i = 0; i < searchHits.length; i++) {
                    ids.add(Long.parseLong(searchHits[i].getId()));
                    Map<String, Object> source = searchHits[i].getSourceAsMap();
                    datas.add(source);
                }
            }
        }
        List<HouseOverview> houseOverviews=new ArrayList<>();
        if (!CollectionUtils.isEmpty(ids)) {
            houseOverviews = selectHouseByIds(ids, houseCriteria.getOrderStr(), houseCriteria.getOrder());
        }
        /*List<HouseOverview> houseOverviews=new ArrayList<>();
        if (!CollectionUtils.isEmpty(ids)) {
             houseOverviews = selectHouseByIds(ids,"insert_time","ASC");
        }*/
        jsonObject.put("data",houseOverviews);
        jsonObject.put("page",houseCriteria.getCurrentPage());
        return jsonObject;
    }

    @Override
    public List<HouseMapCriteria> queryCityMapCount(HouseMapCriteria houseCriteria) {
        int zoom=houseCriteria.getZoom();
        houseCriteria.setMin_lng(houseCriteria.getMin_lng()-0.1);
        houseCriteria.setMax_lng(houseCriteria.getMax_lng()+0.1);

        houseCriteria.setMin_lat(houseCriteria.getMin_lat()-0.1);
        houseCriteria.setMax_lat(houseCriteria.getMax_lat()+0.1);
        if(zoom<=13){//一级菜单
            return houseBaseMapper.queryCountyCount(houseCriteria);
        }else if(zoom>= 14 &&zoom<= 15){//二级
            return houseBaseMapper.queryTownCount(houseCriteria);
        }else if(zoom>=16){//三级
            return houseBaseMapper.queryStreetMapCount(houseCriteria);
        }
        return null;
    }

    public List<HouseMapCriteria> queryCityMapCount2(HouseMapCriteria houseCriteria) {
        int zoom=houseCriteria.getZoom();
        if(zoom<=13){//一级菜单
            return houseBaseMapper.queryCountyCount(houseCriteria);
        }else if(zoom>= 14 &&zoom<= 15){//二级
            return houseBaseMapper.queryTownCount(houseCriteria);
        }else if(zoom>=16){//三级
            return houseBaseMapper.queryStreetMapCount(houseCriteria);
        }
        return null;
    }

    /**
     * 地图搜索过滤筛选
     * 筛选条件如下：
     * 房屋类型
     * 房屋价格
     * 房屋朝向
     * 房屋特色
     * @param houseMapCriteria
     * @param boolQueryBuilder
     * @return
     */
    private String[]  chooseHouseType(HouseMapCriteria houseMapCriteria,BoolQueryBuilder boolQueryBuilder){
        String result="";
        String typeStr=houseMapCriteria.getType();
        if(!StringUtils.isBlank(typeStr)){//几居室
            String[] types = typeStr.split(",");
            int[] es=new int[4];
            int[] os=new int[4];

            boolean isE=false;//整租标志
            boolean isO=false;//直租标志
            boolean noLimit=true;//不限标志
            for(String type:types){
                int a=Math.abs(Integer.parseInt(type));
                if(a<4){//荣者整租
                    isE=true;
                    es[a]=a;
                    if(a!=0){
                        noLimit=false;
                    }
                }else if(a>3){//业主直租
                    isO=true;
                    os[a-4]=a-4;
                    if(a!=4){
                        noLimit=false;
                    }
                }
            }
            //update by chengjia 2018-4-12 11:01:32
            //TODO:目前直租包含有整租和合租，表示整租合租互斥，但直租和合租整租并存
            if(isE){
                //select * from house_base where isEntireRent=1 and roomNum in(x,x,x,x);
                boolQueryBuilder.must(QueryBuilders.termQuery("isEntireRent", true));
                if(!noLimit){
                    boolQueryBuilder.must(QueryBuilders.termsQuery("roomNum",es));
                }
            }
            if(isO){
                ////select * from house_base where isOwnerRent=1 and roomNum in(x,x,x,x);
                boolQueryBuilder.must(QueryBuilders.termQuery("isOwnerRent", true));
                if (!noLimit) {
                    boolQueryBuilder.must(QueryBuilders.termsQuery("roomNum",os));
                }
            }


        }
        //////////////////////////////////////////////////
        String priceStr=houseMapCriteria.getPrice();
        if(!StringUtils.isBlank(priceStr)){//价格
            String[] price = priceStr.split(",");
            if(price.length!=0){
                if(priceStr.startsWith(",")){
                    boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").lte(price[1]));
                }else if(priceStr.endsWith(",")){
                    boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").gte(price[0]));
                }else{
                    boolQueryBuilder.must(QueryBuilders.rangeQuery("rent").gte(price[0]).lte(price[1]));
                }
            }
        }
//////////////////////////////////////////////////
        if(houseMapCriteria.getFace()!=0){//朝向
            boolQueryBuilder.must(QueryBuilders.termsQuery("orientation",houseMapCriteria.getFace()+""));
        }
//////////////////////////////////////////////////
        if(!StringUtils.isBlank(houseMapCriteria.getFeature())){//房屋特色
            houseTagQuery(houseMapCriteria.getFeature(),boolQueryBuilder);
        }

        if(!StringUtils.isBlank(houseMapCriteria.getAround())){//房屋周边
            houseTagQuery(houseMapCriteria.getAround(),boolQueryBuilder);
        }

        //TODO:暂无
        if(houseMapCriteria.getLeasetype()!=0){//租约类型 年租 短租

        }

        if(houseMapCriteria.getTag()!=0){//房屋状态 可出租 可预订 rendStatus 1 可入住 2 已出租 3 锁住
            boolQueryBuilder.must(QueryBuilders.termsQuery("rendStatus",houseMapCriteria.getTag()+""));
        }

        return null;
    }

    /**
     * 地图更多筛选
     * @param dataStr
     * @param boolQueryBuilder
     */
    private void houseTagQuery(String dataStr,BoolQueryBuilder boolQueryBuilder){
        String[] tags = dataStr.split(",");
        int[] datas=new int[tags.length];
        if(tags.length!=0){
            for (String tag:tags){
                switch (tag){
                    case "14": boolQueryBuilder.must(QueryBuilders.termsQuery("isElevator",true));break;
                }
            }
        }
        boolQueryBuilder.must(QueryBuilders.termsQuery("tagList",tags));
        //首次出租5  独立卫生间3 独立阳台4
        //集体供暖10 独立供暖12 中央供暖11
        //智能锁13 有电梯14

        //离地铁近1 绿化率高4
    }
}
